using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using BizElements.BusinessLayer;

namespace BizElements.Web
{
    /// <summary>
    /// Creates grid footers which compute and display the maximum value in a numeric column.
    /// </summary>
    [Serializable]
    public sealed class GridFooterMax : GridFoooterNumericAggregateBase
    {
        #region Constructors.

        /// <summary>
        /// Initializes a new instance of <b>GridFooterMax</b> class.
        /// </summary>
        /// <param name="valueFieldName">Name of the numeric field/columns to which aggregate is applied.</param>
        /// <param name="valueDataType">Type of values contained in the field. Only numeric types are allowed.</param>
        public GridFooterMax(string valueFieldName, Type valueDataType)
            : base(valueFieldName, valueDataType)
        {
        }

        /// <summary>
        /// Initializes a new instance of <b>GridFooterMax</b> class.
        /// </summary>
        /// <param name="valueFieldName">Name of the numeric field/columns to which aggregate is applied.</param>
        /// <param name="valueDataType">Type of values contained in the field. Only numeric types are allowed.</param>
        /// <param name="resultFormat">Result string format. Eg: "MAX: {0}". Nullable.</param>
        public GridFooterMax(string valueFieldName, Type valueDataType, string resultFormat)
            : base(valueFieldName, valueDataType, resultFormat)
        {
        }

        /// <summary>
        /// Initializes a new instance of <b>GridFooterMax</b> class.
        /// </summary>
        /// <param name="valueFieldName">Name of the numeric field/columns to which aggregate is applied.</param>
        /// <param name="valueDataType">Type of values contained in the field. Only numeric types are allowed.</param>
        /// <param name="resultFormat">Result string format. Eg: "MAX: {0}". Nullable.</param>
        /// <param name="formatter">Formats numbers values. Nullable.</param>
        /// <param name="placementColumn">The name of the field/column in whose footer the computed value will be displayed. Nullable.</param>
        public GridFooterMax(string valueFieldName, Type valueDataType, string resultFormat, IMessageFormatter formatter, string placementColumn)
            : base(valueFieldName, valueDataType, resultFormat, formatter, placementColumn)
        {
        }

        #endregion

        #region Compute aggregate.

        /// <summary>
        /// Computes and returns the integral sum of the provided values.
        /// </summary>
        /// <param name="numericValues">A collection of numeric values which are convertible to <see cref="System.Int64"/>.</param>
        /// <returns>Aggregate value.</returns>
        protected override long ComputeIntegralAggregate(IEnumerable numericValues)
        {
            long? min = null;
            foreach (object value in numericValues)
            {
                long currValue = Convert.ToInt64(value);
                if (min == null)
                    min = currValue;
                else if (currValue > min.Value)
                    min = currValue;
            }

            return min ?? 0;
        }

        /// <summary>
        /// Computes and returns the floating point sum of the provided values.
        /// </summary>
        /// <param name="numericValues">A collection of numeric values which are convertible to <see cref="System.Decimal"/>.</param>
        /// <returns>Aggregate value.</returns>
        protected override decimal ComputeFloatingPointAggregate(IEnumerable numericValues)
        {
            decimal? min = null;
            foreach (object value in numericValues)
            {
                decimal currValue = Convert.ToDecimal(value);
                if (min == null)
                    min = currValue;
                else if (currValue > min.Value)
                    min = currValue;
            }

            return min ?? 0;
        }

        #endregion
    }
}